package cn.wolfcode.luowowo.website.web.controller;

import cn.wolfcode.luowowo.article.domain.Destination;
import cn.wolfcode.luowowo.article.domain.Travel;
import cn.wolfcode.luowowo.article.service.IDestinationService;
import cn.wolfcode.luowowo.article.service.ITravelService;
import cn.wolfcode.luowowo.cache.service.IScenicCommentCacheService;
import cn.wolfcode.luowowo.cache.service.IStrategyStatisVOService;
import cn.wolfcode.luowowo.cache.service.ITravelStatisVoService;
import cn.wolfcode.luowowo.cache.service.IUserInfoRedisService;
import cn.wolfcode.luowowo.cache.util.RedisKeysUtil;
import cn.wolfcode.luowowo.cache.vo.ScenicStatisVo;
import cn.wolfcode.luowowo.cache.vo.StrategyStatisVO;
import cn.wolfcode.luowowo.cache.vo.TravelStatisVo;
import cn.wolfcode.luowowo.comment.domain.ScenicComment;
import cn.wolfcode.luowowo.comment.domain.TravelComment;
import cn.wolfcode.luowowo.comment.service.IScenicCommentService;
import cn.wolfcode.luowowo.comment.service.ITravelCommentService;
import cn.wolfcode.luowowo.exception.LogicException;
import cn.wolfcode.luowowo.hotel.domain.HotelOrder;
import cn.wolfcode.luowowo.hotel.service.IHotelOrderService;
import cn.wolfcode.luowowo.member.domain.UserInfo;
import cn.wolfcode.luowowo.member.service.IUserInfoService;
import cn.wolfcode.luowowo.search.service.HotelTemplateSearchService;
import cn.wolfcode.luowowo.search.template.HotelTemplate;
import cn.wolfcode.luowowo.ticket.domain.Payment;
import cn.wolfcode.luowowo.ticket.service.IPaymentService;
import cn.wolfcode.luowowo.util.AjaxResult;
import cn.wolfcode.luowowo.website.annotation.UserParam;
import cn.wolfcode.luowowo.website.util.CookieUtil;
import cn.wolfcode.luowowo.website.util.UploadUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.wolfcode.luowowo.website.util.ConstantUtil.USER_INFO_TOKEN_COOKIE_NAME;

@Controller
@RequestMapping("/mine")
public class MineController {

    @Reference
    private IUserInfoService userInfoService;

    @Reference
    private ITravelService travelService;

    @Reference
    private IDestinationService destinationService;

    @Reference
    private ITravelStatisVoService travelStatisVoService;

    @Reference
    private IStrategyStatisVOService strategyStatisVOService;

    @Reference
    private ITravelCommentService travelCommentService;

    @Reference
    private IUserInfoRedisService userInfoRedisService;

    @Reference
    private IHotelOrderService hotelOrderService;

    @Reference
    private IScenicCommentCacheService scenicCommentCacheService;

    @Reference
    private IScenicCommentService scenicCommentService;

    @Reference
    private IPaymentService paymentService;

    @Reference
    private HotelTemplateSearchService hotelTemplateSearchService;

    @RequestMapping("/home")
    public Object mine(Model model, @UserParam UserInfo user) {
        if (user == null) {
            throw new LogicException("请先登录");
        }
        // 根据用户id查询游记
        List<Travel> travels = travelService.queryByAuthorId(user.getId());
        // 景点点评
        // 获取游记vo对象 获取吐司导航
        List<Map<String, Object>> list = new ArrayList<>();
        for (Travel travel : travels) {
            Map<String, Object> map = new HashMap<>();
            TravelStatisVo vo = travelStatisVoService.getTravelStatisVoByTravelId(travel.getId());
            List<Destination> toasts = destinationService.getToasts(travel.getDest().getId());
            map.put("travel", travel);
            map.put("vo", vo);
            map.put("toast", toasts.get(0));
            list.add(map);
        }
        model.addAttribute("list", list);
        // 游记篇数
        model.addAttribute("count", travels.size());
        // 关注数
        int attention = userInfoService.getCountForAttention(user.getId());
        model.addAttribute("attention", attention);
        // 粉丝数
        int fans = userInfoService.getCountForFans(user.getId());
        model.addAttribute("fans", fans);
        // 回显关注的人
        // 拿到关注的用户的id
        List<Long> attArray = userInfoService.getAttentionId(user.getId());
        List<UserInfo> users = userInfoService.queryAttentionByIds(attArray);
        model.addAttribute("users", users);
        // 我的点评
        List<ScenicComment> scenicComments = scenicCommentService.getByUserId(user.getId());
        model.addAttribute("scenicComments", scenicComments);
        // 点评数量
        model.addAttribute("sCount", scenicComments.size());
        return "mine/homepage";
    }

    @RequestMapping("/mytravelnotes")
    public Object mytravelnotes(Model model, @UserParam UserInfo user) {
        if (user == null) {
            throw new LogicException("请先登录");
        }
        List<Travel> travels = travelService.queryByAuthorId(user.getId());
        List<Map<String, Object>> list = new ArrayList<>();
        int replynumSum = 0;
        int viewnumSum = 0;
        for (Travel travel : travels) {
            Map<String, Object> map = new HashMap<>();
            TravelStatisVo vo = travelStatisVoService.getTravelStatisVoByTravelId(travel.getId());
            replynumSum = replynumSum + vo.getReplynum();
            viewnumSum = viewnumSum + vo.getViewnum();
            List<Destination> toasts = destinationService.getToasts(travel.getDest().getId());
            map.put("travel", travel);
            map.put("vo", vo);
            map.put("toast", toasts.get(0));
            list.add(map);
        }
        model.addAttribute("list", list);
        model.addAttribute("replynumSum", replynumSum);
        model.addAttribute("viewnumSum", viewnumSum);
        // 游记篇数
        model.addAttribute("count", travels.size());
        return "mine/mytravelnotes";
    }

    @RequestMapping("/review")
    public Object review(Model model, @UserParam UserInfo user) {
        if (user == null) {
            throw new LogicException("请先登录");
        }
        // 查询我的点评
        List<ScenicComment> scenicComments = scenicCommentService.getByUserId(user.getId());
        model.addAttribute("scenicComments", scenicComments);
        return "mine/review";
    }

    @RequestMapping("/travelcollection")
    public Object travelcollection(Model model, @UserParam UserInfo user) {
        if (user == null) {
            throw new LogicException("请先登录");
        }
        // 游记收藏(拿到用户收藏的游记列表travelVo)
        List<TravelStatisVo> travelStatisVos = travelStatisVoService.getTravelStatisVoByUserId(user.getId());
        model.addAttribute("travelVos", travelStatisVos);
        // 攻略收藏(拿到用户收藏的游记列表strategyVo)
        List<StrategyStatisVO> strategyStatisVOS = strategyStatisVOService.getStrategyStatisVoByUserId(user.getId());
        model.addAttribute("strategyVos", strategyStatisVOS);
        // 地点收藏(拿到用户收藏的游记列表scenicVo)
        List<ScenicStatisVo> scenicStatisVOS = scenicCommentCacheService.getScenicStatisVoByUserId(user.getId());
        // 从redis中获取用户收藏的酒店编号
        List<Long> hotelIds = userInfoRedisService.getHotelIdByUserId(user.getId());
        // 酒店收藏
        List<HotelTemplate> hotelTemplates = hotelTemplateSearchService.getHotelByHotelIds(hotelIds);
        model.addAttribute("hotelTemplates", hotelTemplates);
        model.addAttribute("scenicVos", scenicStatisVOS);
        return "mine/travelcollection";
    }

    @RequestMapping("/setting")
    public Object setting(Model model, @UserParam UserInfo user) {
        if (user == null) {
            throw new LogicException("请先登录");
        }
        return "mine/setting";
    }

    @RequestMapping("/saveOrUpdate")
    @ResponseBody
    public Object saveOrUpdate(UserInfo userInfo, HttpServletRequest request) {
        if (userInfo == null) {
            throw new LogicException("参数错误");
        }
        userInfoService.saveOrUpdate(userInfo);
        UserInfo user = userInfoService.get(userInfo.getId());
        String token = CookieUtil.getToken(request, USER_INFO_TOKEN_COOKIE_NAME);
        String key = RedisKeysUtil.USER_LOGIN_TOKEN.join(token);
        // 修改redis中的用户信息
        userInfoRedisService.addToken(key, user);
        // 共享到session中
        request.getSession().setAttribute("userInfo", user);
        return AjaxResult.SUCCESS;
    }

    @Value("${file.path}")
    private String basePath;

    @RequestMapping("/uploadImg")
    @ResponseBody
    public Object uploadImg(MultipartFile files, @UserParam UserInfo userInfo, HttpServletRequest request) {
        String url = UploadUtil.upload(files, basePath);
        userInfoService.updateHeadImgUrl("/" + url, userInfo.getId());
        userInfo.setHeadImgUrl("/" + url);
        String token = CookieUtil.getToken(request, USER_INFO_TOKEN_COOKIE_NAME);
        String key = RedisKeysUtil.USER_LOGIN_TOKEN.join(token);
        userInfoRedisService.addToken(key, userInfo);
        request.getSession().setAttribute("userInfo", userInfo);
        return url;
    }

    @RequestMapping("/myorder")
    public Object myorder(Model model, @UserParam UserInfo user) {
        if (user == null) {
            throw new LogicException("请先登录");
        }
        // 酒店订单
        List<HotelOrder> hotelOrders = hotelOrderService.queryUserHotelOrderByUserId(user.getId());
        model.addAttribute("orders", hotelOrders);
        // 门票订单
        List<Payment> payments = paymentService.getByUserId(user.getId());
        model.addAttribute("payments", payments);
        return "mine/myorder";
    }

    /**
     * 发送验证码
     *
     * @param phone
     * @return
     */
    @RequestMapping("/sendPhoneVerifyCode")
    @ResponseBody
    public Object sendVerifyCodeByUpdate(String phone) {
        userInfoService.sendVerifyCode(phone);
        return AjaxResult.SUCCESS;
    }

    /**
     * 发送新的手机的验证码
     *
     * @param newMobile
     * @return
     */
    @RequestMapping("/sendNewPhoneVerifyCode")
    @ResponseBody
    public Object sendNewPhoneVerifyCode(String newMobile) {
        userInfoService.sendVerifyCode(newMobile);
        return AjaxResult.SUCCESS;
    }

    /**
     * 验证验证码是否正确
     *
     * @param phone
     * @return
     */
    @RequestMapping("/checkVerifyCode")
    @ResponseBody
    public Object checkVerifyCode(String phone, String code) {
        String key = RedisKeysUtil.VERIFY_CODE.join(phone);
        String windowCode = userInfoRedisService.getVerifyCode(key);
        System.out.println(windowCode);
        if (windowCode == null || !windowCode.equalsIgnoreCase(code)) {
            throw new LogicException("验证码失效或错误");
        }
        return AjaxResult.SUCCESS;
    }

    /**
     * 验证新的验证码是否正确
     * 然后就是修改该手机号了
     *
     * @param
     * @return
     */
    @RequestMapping("/setNewPhone")
    @ResponseBody
    public Object setNewPhone(String newMobile, String verifyCode, @UserParam UserInfo userInfo) {
        String key = RedisKeysUtil.VERIFY_CODE.join(newMobile);
        String windowCode = userInfoRedisService.getVerifyCode(key);
        System.out.println(newMobile);
        System.out.println(windowCode);
        if (windowCode == null || !windowCode.equalsIgnoreCase(verifyCode)) {
            throw new LogicException("验证码失效或错误");
        }
        if (newMobile.equals(userInfo.getPhone())) {
            throw new LogicException("新手机号与旧手机号重复了");
        }
        //userInfoService.updatePhone(userInfo.getPhone(),newMobile);
        userInfoService.updatePhone(userInfo.getPhone(), newMobile);
        return AjaxResult.SUCCESS;
    }

}
